package fr.esisar.cs420.graphproj;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;



import oracle.jdbc.pool.OracleDataSource;

/**
 * Le Modele gere toutes les requetes avec la base de donnees
 */

public class Modele {
	/**
	 * L'attribut conn represente la connection avec la base de donnee, il est initialise a l'instentiation de Modele
	 */
	Connection conn;
	
	/**
	 * Constructeur de Modele permet d'initialiser la connection avec la base de donnee
	 * @param st Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public Modele(StringBuilder st){
		try{			
			String url = "jdbc:oracle:thin:@localhost:1521:XE";	
			
			// Create a OracleDataSource instance and set properties
			OracleDataSource ods = new OracleDataSource();
			ods.setUser("userir");
			ods.setPassword("userir");
			ods.setURL(url);	
			
			// Connect to the database
			conn = ods.getConnection();
			st.replace(0, st.length(), "The Connexion to the database was successful");			
		}
		catch (SQLException e){	
			st.replace(0, st.length(), e.getMessage());
			
		}
	}
	
	/**
	 * Methode permettant de se deconnecter de la base de donnee 
	 * @param st Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public void deconnection(StringBuilder st){
		try{
			// Close the connection
			conn.close();
			st.replace(0, st.length(), "You are now disconnected");
		}
		catch (SQLException e){	st.replace(0, st.length(), e.getMessage());}	
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin de recuperer l'idCompte et le mdp correspondant au mail donnee en parametre
	 * @param mail 	Correspond au loggin du Compte
	 * @param mdp1	Contiendra le mot de passe du compte a la fin de l'execution de la methode
	 * @param st 	Permet de faire remonter des infomations jusqu'a la Vue
	 * @return		Renvoi l'idCompte correspondant au loggin mail
	 */
	public int connectionClient(String mail,StringBuilder mdp1,StringBuilder st) {
		int idCompte=0;
		try
		{			
			// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en read only
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			// Select la tuile correspondant au client
			ResultSet rset =stmt.executeQuery("SELECT idCompte,mdp FROM Compte WHERE mail LIKE '"+mail+"'");

			//Recuperation de l'id et du mot de passe
			if(rset.next()){
				mdp1.replace(0,mdp1.length(), rset.getNString(2));
				idCompte = rset.getInt("idCompte");
			}
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");

			// Close the Statement
			stmt.close();
		} 
		catch (SQLException e){	st.replace(0, st.length(), e.getMessage());}
		
		return idCompte;
	}

	/**
	 * Methode permettant de generer une requete SQL afin de rajouter un Compte a la base de donnee
	 * @param mail 			Correspond au loggin du Compte
	 * @param mdp			Correspond au mot de passe du Compte
	 * @param nom 			Correspond au nom du client
	 * @param prenom		Correspond au prenom du client
	 * @param adrpostale	Correspond a l'adresse postale du Client
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public void inscription(String mail, String mdp, String nom, String prenom, String adrpostale,StringBuilder st) {
		try{
			// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			// Insertion dans la base de donn�es
			stmt.executeUpdate("INSERT into Compte(mail,mdp) values('"+mail+"','"+mdp+"')");
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			st.replace(0, st.length(), "Your new account has been created");

			// Close the Statement
			stmt.close();
			
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(), e.getMessage());
		}
		
	}

	/**
	 * Methode permettant de generer une requete SQL afin de rajouter une Photo a la base de donnee
	 * @param path 				Correspond au repertoir ou est stocke la photo
	 * @param appareil			Correspond au type d'appareil avec lequel la photo a ete prise
	 * @param objectif 			Correspond au type d'objectif avec lequel la photo a ete prise
	 * @param distancefocale	Correspond a la distance focale avec laquel la photo a ete prise
	 * @param sensibiliteISO	Correspond a la sensibilite iso avec laquel la photo a ete prise
	 * @param ouverture			Correspond a l'ouverture avec laquel la photo a ete prise
	 * @param vitesseobturation Correspond a la vitesse d'obturation avec laquel la photo a ete prise
	 * @param resolution		Correspond a la resolution avec laquel la photo a ete prise
	 * @param idCompte			Correspond a l'idCompte du client qui rajoute une photo
	 * @param st 				Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public void upload(String path, String appareil, String objectif,int distancefocale, String sensibiliteISO, int ouverture,int vitesseobturation, String resolution,int idCompte, StringBuilder st) {
		
		try
		{
			// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			// Insertion dans la base de donnees
			stmt.executeUpdate("INSERT INTO Photo(path,appareil,objectif,distancefocale,sensibiliteISO,ouverture,vitesseobturation,resolution,fkCompte) VALUES ('"+path+"','"+appareil+"','"+objectif+"',"+distancefocale+",'"+sensibiliteISO+"',"+ouverture+","+vitesseobturation+",'"+resolution+"',"+idCompte+")");
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			

			// Close the Statement
			stmt.close();

			// Close the connection
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
		}
		
	}
	/**
	 * Methode permettant de generer une requete SQL afin de rajouter un Document a la base de donnee
	 * @param titre 			Correspond au titre du document
	 * @param soustitre			Correspond au sous-titre du document
	 * @param idCompte			Correspond a l'idCompte du client qui rajoute un document
	 * @param st 				Permet de faire remonter des infomations jusqu'a la Vue
	 * @return					Renvoi l'idDocument afin de faire le lien avec un Livre ou un Album
	 */
	public int newDocument(int idCompte,String titre, String soustitre, int isPublic,StringBuilder st) {
		int idDocument=0;
		try
		{
			// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			// Insertion dans la base de donn�es
			stmt.executeUpdate("INSERT INTO Document(titre,soustitre,isPublic,fkCompte) VALUES ('"+titre+"','"+soustitre+"',"+isPublic+","+idCompte+")");
			
			ResultSet rset =stmt.executeQuery("SELECT MAX(idDocument) FROM Document");
			if(rset.next()){
				idDocument=rset.getInt("MAX(idDocument)");
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();			
		}
		return idDocument;
		
		
	}

	/**
	 * Methode permettant de generer une requete SQL afin de rajouter un Album a la base de donnee
	 * @param idDocument		Correspond a l'idDocument du Document auquel il est associe afin de faire l'heritage
	 * @param st 				Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public void newAlbum(int idDocument,StringBuilder st) {
		try
		{
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			// Insertion dans la base de donn�es
			stmt.executeUpdate("INSERT INTO Album(fkDocument) VALUES ("+idDocument+")");
			
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			
		}
		
	}

	/**
	 * Methode permettant de generer une requete SQL afin de rajouter un Livre a la base de donnee
	 * @param postface 			Correspond a la postface du Livre
	 * @param preface			Correspond a la peface du Livre
	 * @param idDocument		Correspond a l'idCompte du client qui rajoute un document
	 * @param st 				Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public void newLivre(int idDocument,String postface, String preface, StringBuilder st) {
		try
		{
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			// Insertion dans la base de donn�es
			stmt.executeUpdate("INSERT INTO Livre(postface,preface,fkDocument) VALUES ('"+postface+"','"+preface+"',"+idDocument+")");
			
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			
		}
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin de rajouter une Photo a un Document
	 * @param titre				Correspond au titre de la Photo
	 * @param commentaire		Correspond au commentaire associe a la Photo
	 * @param idDocument		Correspond a l'idCompte du client qui rajoute un document
	 * @param st 				Permet de faire remonter des infomations jusqu'a la Vue
	 * @param idPhoto			Correspond à l'idPhoto de la Photo ajoutee
	 */
	public void ajoutPhoto(int idDocument, int idPhoto, String titre, String commentaire,StringBuilder st) {
		int nbordre=0;
		try
		{
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			ResultSet rset =stmt.executeQuery("SELECT MAX(nbordre) FROM Appartient WHERE idDocument="+idDocument);
			if(rset.next()){
				nbordre=rset.getInt("MAX(nbordre)") + 1;
			}
			// Insertion dans la base de donn�es
			stmt.executeUpdate("INSERT INTO Appartient(idPhoto,idDocument,nbordre,titre,commentaire) VALUES ("+idPhoto+","+idDocument+","+nbordre+",'"+titre+"','"+commentaire+"')");
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			
		}
		
	}

	/**
	 * Methode permettant de generer une requete SQL afin de recuperer l'idPhoto de la Photo situee dans le repertoire dir
	 * @param dir 	Correspond au repertoire de la Photo
	 * @param st 	Permet de faire remonter des infomations jusqu'a la Vue
	 * @return 		Renvoi l'idPhoto corrspondant au repertoire dir
	 */
	public int getidPhoto(String dir,StringBuilder st) {
		int idPhoto=0;
		try
		{
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			// Selection dans la base de donn�es	
			ResultSet rset =stmt.executeQuery("SELECT idPhoto FROM Photo WHERE path LIKE'"+dir+"'");
			if(rset.next()){
				idPhoto=rset.getInt("idPhoto");
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			
		}
		return idPhoto;
		
	}

	/**
	 * Methode permettant de generer une requete SQL afin de savoir si un document est partage ou pas
	 * @param idDocument 	Correspond a l'idDocument du Document dont on veut savoir si il est partage ou pas
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return 				Renvoi 1 si le document est partage, 0 sinon
	 */
	public int isPublic(int idDocument,StringBuilder st){
		int isPublic=0;
		try
		{
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");			

			// Selection dans la base de donn�es	
			ResultSet rset =stmt.executeQuery("SELECT isPublic FROM Document WHERE idDocument="+idDocument);
			if(rset.next()){
				isPublic=rset.getInt("isPublic");
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			
		}
		return isPublic;
	}
	
	
	/**
	 * Methode permettant de generer une requete SQL afin de recuperer l'idDocument d'un document (Livre ou Album)  de la base de donnee
	 * @param id 			Correspond a l'id du document (Livre ou Album)
	 * @param type			Correspond au type du document (livre ou album)
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return 				Renvoi l'idDocument du document id (Livre ou Album)
	 */
	public int getidDocument(int id, Document.type type , StringBuilder st){
		int idDocument=0;
		try
		{
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture ecriture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			if (type==Document.type.Album){
				rset =stmt.executeQuery("SELECT fkDocument FROM Album WHERE idAlbum="+id);
			}
			else{
				rset =stmt.executeQuery("SELECT fkDocument FROM Livre WHERE idLivre="+id);
			}
			if(rset.next()){
				idDocument=rset.getInt("fkDocument");
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();			
		}
		return idDocument;
	}

	/**
	 * Methode permettant de generer une requete SQL afin de recuperer les Photo du Compte
	 * @param compte 		Correspond a l'id du Compte
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return 				Renvoi une liste chainee des Photos
	 * @see	Photo
	 */
	public Photo getAccountPhotos(int compte, StringBuilder st) {
		Photo ph=null,phprec=null,tete=null;
		try
		{
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT idPhoto,path FROM Photo WHERE fkCompte="+compte);

			while (rset.next())
			{
				ph= new Photo(rset.getInt("idPhoto"),rset.getNString("path"),phprec);
				if(tete==null)		tete=ph;
				if(phprec!=null)	phprec.setNext(ph);

				phprec=ph;
				
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

			return tete;
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			return null;
			
		}
	}

	/**
	 * Methode permettant de generer une requete SQL afin de recuperer les Photo d'un Document
	 * @param idDocument 	Correspond a l'id du Document
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return 				Renvoi une liste chainee des Photos
	 * @see	Photo
	 */
	public Photo getDocumentPhotos(int idDocument, StringBuilder st) {
		Photo ph=null,phprec=null;
		try
		{
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");

			rset =stmt.executeQuery("SELECT Appartient.idPhoto,path,nbordre,titre,commentaire FROM Appartient,Photo WHERE idDocument="+idDocument+ "AND Appartient.idPhoto=Photo.idPhoto");


			while (rset.next())
			{
				ph=new Photo(rset.getInt("idPhoto"),Photo.type.Photo,Photo.localisation.Distante,phprec,rset.getNString("path"),rset.getNString("titre"),rset.getNString("commentaire"));
				if(phprec!=null){
					phprec.setNext(ph);
				}
				phprec=ph;
				
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			// Close the Statement
			stmt.close();

			return ph;
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			return null;			
		}		
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin de savoir si le Client possede le Document
	 * @param compte 		Correspond a l'id du Compte
	 * @param idDocument	Correspond a l'id du Document
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return 				Renvoi un booleen: vrai si il le possede; faux sinon
	 */
	public Boolean possedeDoc(int compte, int idDocument, StringBuilder st) {
		Boolean possede=false;
		try
		{
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT fkCompte FROM Document WHERE idDocument="+idDocument);
			if(rset.next()){
				if(rset.getInt("fkCompte")==compte){
					possede=true;
				}
			}

			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			
		}	
		return possede;
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin de rajouter la Photo d'idPhoto au Livre idLivre
	 * @param idLivre 		Correspond a l'id du Livre
	 * @param idPhoto 		Correspond a l'id du Photo
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public void setCouverture(int idLivre,int idPhoto,StringBuilder st) {
		try{
			// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			// Insertion dans la base de donn�es
			stmt.executeUpdate("UPDATE Livre SET fkLivre="+idPhoto+" WHERE idLivre="+idLivre);
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			st.replace(0, st.length(), "Covert added");

			// Close the Statement
			stmt.close();
			
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(), e.getMessage());
		}
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin de recuperer la Photo de couverture du Livre idLivre
	 * @param idLivre 		Correspond a l'id du Livre
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return				Renvoi la Photo de couverture
	 * @see Photo
	 */
	public Photo getCouverture(int idLivre, StringBuilder st) {
		try
		{
			Photo ph=null;
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT path FROM Photo WHERE idPhoto IN (SELECT fkPhoto FROM Livre WHERE idLivre="+idLivre+")");

			ph=new Photo(rset.getInt("fkPhoto"),rset.getNString("path"), (Photo)null);
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

			return ph;
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			return null;
			
		}		
	}

	/**
	 * Methode permettant de generer une requete SQL afin recuperer les Livres associes au Compte connecte
	 * @param compte 		Correspond a l'id du Compte
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return				Renvoi la liste chainee des Livres appartenants au Compte
	 * @see	Document
	 */
	public Document getAccountLivres(int compte, StringBuilder st) {
		Document doc=null,docprec=null;
		try
		{
			
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT D.titre,L.idLivre FROM Document D,Livre L WHERE L.fkDocument= D.idDocument AND D.fkCompte="+compte);

			if(rset.next()){
				doc=new Document(Document.recherche.Livre, Document.type.Livre, rset.getInt("idLivre"), rset.getNString("titre"));
				docprec=doc;
			}
			while (rset.next())
			{
				doc=new Document(Document.type.Livre, rset.getInt("idLivre"), rset.getNString("titre"),doc);
			
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			
		}
		return docprec;
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin recuperer les Albums associes au Compte connecte
	 * @param compte 		Correspond a l'id du Compte
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return				Renvoi la liste chainee des Albums appartenants au Compte
	 * @see	Document
	 */
	public Document getAccountAlbum(int compte, StringBuilder st) {
		Document doc=null,docprec=null;
		try
		{
			
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT D.titre,A.idAlbum FROM Document D,Album A WHERE A.fkDocument= D.idDocument AND D.fkCompte="+compte);
			if(rset.next()){
				doc=new Document(Document.recherche.Album, Document.type.Album, rset.getInt("idAlbum"), rset.getNString("titre"));
				docprec=doc;
			}
			while (rset.next())
			{
				doc=new Document(Document.type.Album, rset.getInt("idAlbum"), rset.getNString("titre"),doc);
			
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();
			
		}
		return docprec;
	}

	/**
	 * Methode permettant de generer une requete SQL afin recuperer les Albums publics
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return				Renvoi la liste chainee des Albums publics
	 * @see	Document
	 */
	public Document getPublicAlbums(StringBuilder st) {
		Document doc=null,docprec=null;
		try
		{
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT D.titre,A.idAlbum FROM Document D,Album A WHERE A.fkDocument= D.idDocument AND D.isPublic="+1);

			if(rset.next()){
				doc=new Document(Document.recherche.Album, Document.type.Album, rset.getInt("idAlbum"), rset.getNString("titre"));
				docprec=doc;
			}
			while (rset.next())
			{
				doc=new Document(Document.type.Album, rset.getInt("idAlbum"), rset.getNString("titre"),doc);
			
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();


		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();			
		}
		return docprec;
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin recuperer les Livre publics
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return				Renvoi la liste chainee des Livres publics
	 * @see	Document
	 */
	public Document getPublicLivres(StringBuilder st) {
		Document doc=null,docprec=null;
		try
		{
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT D.titre,L.idLivre FROM Document D,Livre L WHERE L.fkDocument= D.idDocument AND D.isPublic="+0);

			if(rset.next()){
				doc=new Document(Document.recherche.Livre, Document.type.Livre, rset.getInt("idLivre"), rset.getNString("titre"));
				docprec=doc;
			}
			while (rset.next())
			{
				doc=new Document(Document.type.Livre, rset.getInt("idLivre"), rset.getNString("titre"),doc);
			
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();


		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();			
		}
		return docprec;
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin d'ajouter une Commande a la base de donnee
	 * @param date			Correspond a la date a laquelle la commande a ete faite
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public void newCommande(String date,StringBuilder st) {
		try{
			// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			// Insertion dans la base de donn�es
			stmt.executeUpdate("INSERT into Commande(date,prixtotal) values('"+date+"',0)");
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			st.replace(0, st.length(), "Your new account has been created");

			// Close the Statement
			stmt.close();
			
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(), e.getMessage());
			//e.printStackTrace();
		}
		
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin d'ajouter un tirage a la base de donnee et mettre a jour le prixtotal de la Commande
	 * @param idCommande	Correspond a la Commande a laquelle on ajoute le Tirage
	 * @param idCompte		Correspond au Compte auquel on ajoute le Tirage
	 * @param idDocument	Correspond au Document qui doit etre tire
	 * @param idFormat		Correspond auquel le Document doit etre tire
	 * @param qte			Correspond au nombre de tirage de ce Document
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 */
	public void newTirage(int idCommande,int idDocument,int idCompte,int idFormat, int qte,StringBuilder st) {
		try{
			// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			
			// Insertion dans la base de donn�es
			stmt.executeUpdate("INSERT into Tirage(qte,fkCommande,fkCompte,fkDocument,fkFormat) values("+qte+","+idCommande+","+idCompte+","+idDocument+","+idFormat+")");
			stmt.executeUpdate("UPDATE Commande SET prixtotal=prixtotal+"+qte+"*"+getPrixUnitaire(idFormat,st)+"WHERE idCommande="+idCommande);
			
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			
			st.replace(0, st.length(), "Your new  has been created");

			// Close the Statement
			stmt.close();
			
		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(), e.getMessage());
			//e.printStackTrace();
		}
		
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin d'obtenir le prix unitaire du Format idFormat
	 * @param idFormat		Correspond au Format dont on veut le prix unitaire
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return				Renvoi le prix unitaire
	 */
	public int getPrixUnitaire(int idFormat,StringBuilder st) {
		int prixunitaire=0;
		try
		{
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT prixunitaire FROM Format WHERE idFormat="+idFormat);

			if(rset.next()){
				prixunitaire=rset.getInt("prixunitaire");
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();			
		}
		return prixunitaire;
	}
	
	/**
	 * Methode permettant de generer une requete SQL afin d'obtenir les formats disponibles pour un Livre ou un Album
	 * @param type			Correspond au type de document dont on veut les formats
	 * @param st 			Permet de faire remonter des infomations jusqu'a la Vue
	 * @return				Renvoi une liste chainee de Formats
	 * @see Format
	 */
	public Format getFormatsDocument(Format.type type,StringBuilder st) {
		Format fo=null,foprec=null;
		try
		{
			ResultSet rset;
					// Create a Statement
			Statement stmt = conn.createStatement();

			// Passage de la transaction en lecture �criture avec le niveau d'isolation maximum
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			rset =stmt.executeQuery("SELECT idFormat,prixunitaire,taille FROM Format WHERE type LIKE '"+type.toString()+"'");
			while (rset.next())
			{
				fo=new Format(foprec,type,rset.getFloat("prixunitaire"),rset.getFloat("taille"),rset.getInt("idFormat"));
				if(foprec!=null){
					foprec.setNextFormat(fo);
				}
				foprec=fo;
				
			}
			// Fin de la transaction 
			stmt.executeUpdate("COMMIT");
			

			// Close the Statement
			stmt.close();

		} 
		catch (SQLException e)
		{
			st.replace(0, st.length(),"Erreur SQL :" + e.getMessage());
			e.printStackTrace();			
		}
		return fo;
	}
	
	

}

